using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ThaiLanguageTools;
using ThaiLanguageTools.DataStruct;
using ThaiLanguageTools.DictionaryGui.Properties;
using System.IO;
using System.Diagnostics;

namespace ThaiLanguageTools.DictionaryGui
{
    public partial class MainForm : Form
    {
        RomanizedLookup _lookup;

        XDict _en2thDict;
        XDict _th2enDict;
        StringMapping _thaiToRoman;

        public MainForm()
        {
            InitializeComponent();

            try
            {
                _en2thDict = XDict.Load(FindDataFile(Settings.Default.File_en2thDict));
                _th2enDict = XDict.Load(FindDataFile(Settings.Default.File_th2enDict));
                _thaiToRoman = StringMapping.Load(FindDataFile(Settings.Default.File_romanized));
            }
            catch (FileNotFoundException e)
            {
                // Exit the app
                Application.Exit();
                return;
            }

            _lookup = new RomanizedLookup(_th2enDict, _thaiToRoman);
            rulesDebugPanel.Lookup = _lookup;
        }

        private void tbInput_TextChanged(object sender, EventArgs e)
        {
            // Timer is a hack since I don't want multithreading now.
            // Consider processing on separate thread, just signal the event

            queryStartTimer.Stop();
            queryStartTimer.Start();
        }

        private void queryStartTimer_Tick(object sender, EventArgs e)
        {
            queryStartTimer.Stop();
            QueryThaiPron(tbInput.Text);
            QueryEnglishExact(tbInput.Text);
        }

        string FindDataFile(String fileName)
        {            
            String filePath = Path.Combine(Settings.Default.File_dataPath, fileName);
            // Accept file from C# project directory
            if (!File.Exists(filePath)) { filePath = Path.Combine(@"..\..\", filePath); }

            if (!File.Exists(filePath))
            {
                DialogResult r = MessageBox.Show("File does not exist: " + 
                    "\r\n\t" + filePath + 
                    "\r\nPlease download the Data.*.zip package from:"+
                    "\r\n\t" + Settings.Default.DataDownloadUrl +
                    "\r\n\tExtract it to the application directory and restart the app." +
                    "\r\n" +
                    "\r\nWould you like to visit the download website now?", "File not found", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);

                if (r == DialogResult.Yes)
                {
                    Process.Start(Settings.Default.DataDownloadUrl);
                }

                throw new FileNotFoundException();
            }
            return filePath;
        }

        void QueryEnglishExact(String query)
        {
            List<XDictEntry> english = _en2thDict[tbInput.Text];
            lbResultsEnglish.Items.Clear();
            foreach (XDictEntry e in english)
            {
                String showEntry = e.ToShortString();
                XWordInfo thaiWord;
                if (Utils.TryGetFirst(e.Translations, out thaiWord))
                {
                    List<String> pron = _thaiToRoman.GetMappingsByA(thaiWord.Text);
                    showEntry += "/" + Utils.FirstToString(pron) + "/";
                }
                lbResultsEnglish.Items.Add(showEntry);
            }
        }

        void QueryThaiPron(String query)
        {
            if (query == "")
            {
                lbResultsThai.Items.Clear();
                return;
            }

            // TODO: launch lookup on a separate thread
            QueryList ql = _lookup.GetQueries(query);
            rulesDebugPanel.ShowQueries(ql);

            List<SearchResult> results = new List<SearchResult>();
            foreach (QueryInfo q in ql.GetQueryListCopy(true))
            {
                results.AddRange(_lookup.FindByExactRoman(q));
            }

            // Fill the UI
            lbResultsThai.Items.Clear();
            AddToResults(results);
            if (lbResultsThai.Items.Count == 0) { lbResultsThai.Items.Add("[ No results ]"); }
        }

        void AddToResults(List<SearchResult> results)
        {
            foreach (SearchResult e in results)
            {
                lbResultsThai.Items.Add(e.ToString());
            }
        }

        private void rulesDebugPanel_RulesChanged(object sender, EventArgs e)
        {
            // Restart the query
            QueryThaiPron(tbInput.Text);
        }

    }
}